/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * LogTimeForm.java
 *
 * Created on Oct 5, 2011, 4:38:48 PM
 */
package redclient.ui;

import com.toedter.calendar.JDateChooser;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import redclient.Items.CustomField;
import redclient.Items.Issue;
import redclient.Items.TimeEntry;
import redclient.client.RedManager;
import redclient.webclient.WebClientException;

/**
 *
 * @author Isaias
 */
public class LogTimeForm extends javax.swing.JFrame {

    private Issue issue;
    
    private JTextField txtIssueId;
    
    private JButton playButton;
    
    private JDateChooser dateField;
    
    private JTextField txtSpentHours;
    
    private JComboBox cmbActivity;
    
    private JTextField txtComments;
    
    /** Creates new form LogTimeForm */
    public LogTimeForm() {
        initComponents();
        initComponents(null);
    }
    
    public LogTimeForm(Issue issue)
    {
        super();
        this.issue = issue;
        initComponents();
        initComponents(null);
    }

    private void initComponents(Object object)
    {
        try
        {
            RedManager redManager = RedManager.Connect(issue.getProject().getCredentials());
            Document doc = redManager.GetNewLogTime(issue);
            Elements labels = doc.select("label[for]");
            
            GroupLayout layout = new GroupLayout(mainPanel);
            mainPanel.setLayout(layout);
            
            layout.setAutoCreateGaps(true);
            layout.setAutoCreateContainerGaps(true);
            
            JLabel lblIssueId = new JLabel(labels.select("[for=time_entry_issue_id]").text(), JLabel.TRAILING);
            //mainPanel.add(lblIssueId);
            
            txtIssueId = new JTextField();
            txtIssueId.setEditable(false);
            txtIssueId.setName("time_entry[issue_id]");
            txtIssueId.setText(issue.getId());
            txtIssueId.setHorizontalAlignment(JTextField.RIGHT);
            txtIssueId.setPreferredSize(new Dimension(120, 27));
            
            
            //mainPanel.add(txtIssueId);
            
            playButton = new JButton();
            playButton.setText("Go");
            playButton.setIcon(new ImageIcon(this.getClass().getResource("/redclient/ui/img/play_time_log_icon.png")));
            playButton.addActionListener(new ActionListener(){

                @Override
                public void actionPerformed(ActionEvent ae) {
                    if( "Go".equals(playButton.getText()))
                    {
                        serializeLogTimeEntry();
                    }
                    else
                    {
                        uploadLogTimeEntry();
                    }
                }
                
            });
            
            JLabel lblSpentOn = new JLabel(labels.select("[for=time_entry_spent_on]").text(), JLabel.TRAILING);
            //mainPanel.add(lblSpentOn);
            
            dateField = new JDateChooser();
            dateField.setName("time_entry[spent_on]");
            dateField.setPreferredSize(new Dimension(150, 27));
            
            
            JLabel lblSpentHours = new JLabel(labels.select("[for=time_entry_hours]").text(), JLabel.TRAILING);
                        
            txtSpentHours = new JTextField();
            txtSpentHours.setName("time_entry[hours]");
            txtSpentHours.setHorizontalAlignment(JTextField.RIGHT);
            txtSpentHours.setPreferredSize(new Dimension(120, 27));
            txtSpentHours.setDocument(new JTextFieldLimit(6));
            
            JLabel lblActivityId = new JLabel(labels.select("[for=time_entry_activity_id]").text(), JLabel.TRAILING);
            
            cmbActivity = new JComboBox();
            cmbActivity.setName("time_entry[activity_id]");
            populateComboBox(doc.select("#time_entry_activity_id").first(), cmbActivity);
            cmbActivity.setPreferredSize(new Dimension(170, 27));

                        
            JLabel lblComments = new JLabel(labels.select("[for=time_entry_comments]").text(), JLabel.TRAILING);
                        
            txtComments = new JTextField();
            txtComments.setName("time_entry[comments]");
            txtComments.setPreferredSize(new Dimension(350, 27));
            txtComments.setDocument(new JTextFieldLimit(80));
                        
            layout.setHorizontalGroup(
                layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                        .addComponent(lblIssueId)
                        .addComponent(lblSpentOn)
                        .addComponent(lblSpentHours)
                        .addComponent(lblActivityId)
                        .addComponent(lblComments)
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(txtIssueId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(dateField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(txtSpentHours, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(cmbActivity, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                        .addComponent(txtComments)
                    )
                    .addComponent(playButton)
            );
            
            layout.setVerticalGroup(
                layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblIssueId) 
                        .addComponent(txtIssueId)
                        .addComponent(playButton)
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblSpentOn) 
                        .addComponent(dateField)
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)  
                        .addComponent(lblSpentHours)
                        .addComponent(txtSpentHours)
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblActivityId)
                        .addComponent(cmbActivity)
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblComments) 
                        .addComponent(txtComments)
                    )
            );
            
            mainPanel.setSize(mainPanel.getPreferredSize());
            renderCustomFields(doc);
            this.pack();
        }
        catch(WebClientException wce)
        {
            
        }
        catch(Exception e)
        {
           System.out.println(e.getMessage()); 
        }
        
    }
    
    private void renderCustomFields(org.jsoup.nodes.Document doc)
    {
        customFieldsPanel.removeAll();
        GroupLayout layout = new GroupLayout(customFieldsPanel);
        customFieldsPanel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        
        List<JLabel> labels = new ArrayList<JLabel>();
        List<Component> components = new ArrayList<Component>();
        
        Elements eCustomLabels = doc.select("label[for^=time_entry_custom_field_values]");
        
        for(int i = 0; i < eCustomLabels.size(); i++)
        {
            Element eLabel = eCustomLabels.get(i);
            Element uEl = eLabel.nextElementSibling();
            
            String customLabel = null;
            if( "span".equals(uEl.tagName()) && "required".equals(uEl.attr("class")) ) {
                customLabel = eLabel.text() + " *";
                uEl = uEl.nextElementSibling();
            }
            else{
                customLabel = eLabel.text();
            }
            
            JLabel labelField = new JLabel(customLabel, JLabel.TRAILING);
            labels.add(labelField);
            
            if ( "input".equals(uEl.tagName()) )
            {
                if( "hidden".equalsIgnoreCase(uEl.attr("type")) )
                {
                    uEl = uEl.nextElementSibling();
                }
                if( "text".equalsIgnoreCase(uEl.attr("type"))){
                    if ( uEl.nextElementSibling() != null && "calendar-trigger".equals(uEl.nextElementSibling().attr("class")) )
                    {
                        JDateChooser dateField = new JDateChooser();
                        dateField.setName(uEl.attr("name"));
                        dateField.setDate(new Date());
                        components.add(dateField);
                    }
                    else
                    {
                        JTextField inputText = new JTextField();
                        inputText.setName(uEl.attr("name"));
                        inputText.setText(uEl.val());
                        components.add(inputText);
                    }
                }
                else if ( "checkbox".equalsIgnoreCase(uEl.attr("type"))){
                    JCheckBox checkbox = new JCheckBox();
                    checkbox.setName(uEl.attr("name"));
                    checkbox.setSelected("1".equals(uEl.attr("value")));
                    components.add(checkbox);
                }
            }
            else if ( "textarea".equals(uEl.tagName()) ){
                JTextArea textArea = new JTextArea();
                textArea.setRows(3);
                textArea.setName(uEl.attr("name"));
                textArea.setText(uEl.val());
                labelField.setVerticalAlignment(JLabel.TOP);
                components.add(textArea);
            }
            else if ( "select".equals(uEl.tagName() ) )
            {
                JComboBox selectField = new JComboBox();
                selectField.setName(uEl.attr("name"));
                populateComboBox(uEl, selectField);
                components.add(selectField);
            }
            
        }
        ParallelGroup hLabelsGrp = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
        ParallelGroup hCompsGrp = layout.createParallelGroup(GroupLayout.Alignment.LEADING);
        SequentialGroup sqGrp = layout.createSequentialGroup();
        for( int i = 0; i < labels.size(); i++)
        {
            hLabelsGrp.addComponent(labels.get(i));
            hCompsGrp.addComponent(components.get(i));
            ParallelGroup vGroup = layout.createParallelGroup(GroupLayout.Alignment.BASELINE);
            vGroup.addComponent(labels.get(i))
                  .addComponent(components.get(i));
            sqGrp.addGroup(vGroup);
            
        }
        
        layout.setHorizontalGroup(
                layout.createSequentialGroup()
                      .addGroup(hLabelsGrp)
                      .addGroup(hCompsGrp)
        );
        
        layout.setVerticalGroup(sqGrp);
    }
    
    
    
    private void populateComboBox(Element element, JComboBox combo)
    {
        int selectedIndex = 0;
        for( Iterator<Node> ioption = element.childNodes().iterator(); ioption.hasNext();)
        {
            Node rawNode = ioption.next();
            if( rawNode instanceof Element)
            {
                Element option = (Element)rawNode;
                if ( option.tagName().equals("option"))
                {
                    combo.addItem(
                                        new HtmlOptionLike(option.text(),
                                               "selected".equals(option.attr("selected")),
                                               option.attributes().get("value")
                                           ));
                    if( option.attr("selected") == "selected" )
                    {
                        combo.setSelectedIndex(selectedIndex);
                    }
                }
                selectedIndex++;
            }
        }
    }
    
    private void serializeLogTimeEntry()
    {
        TimeEntry timeEntry = new TimeEntry();
        timeEntry.setIssueId(txtIssueId.getText());
        timeEntry.setSpentOn(dateField.getDate());
        try
        {
            timeEntry.setHours(Float.parseFloat(txtSpentHours.getText()));
        }
        catch(NumberFormatException ife)
        {
            timeEntry.setHours(0);
        }
        timeEntry.setProjectId(issue.getProjectId());
        timeEntry.setComments(txtComments.getText());
        if( cmbActivity.getSelectedIndex() == -1 )
        {
            timeEntry.setActivityId(null);
        }
        
        List<CustomField> customFields = getCustomFieldValues();
        if( customFields != null )
        {
            timeEntry.setCustomFields(customFields);
        }
        
        try
        {
            TimeEntry.Serialize(issue.getProject(), timeEntry);
            Map<Integer, List<TimeEntry>> entries = TimeEntry.getTimeEntries();
            System.out.println(entries);
        }
        catch(Exception ioe)
        {
            System.out.println(ioe.getMessage());
        }
        
    }
    
    private List<CustomField> getCustomFieldValues()
    {
        List<CustomField> customFields = new ArrayList<CustomField>();
        for(Component component : customFieldsPanel.getComponents())
        {
            CustomField cf = null;
            if( component instanceof JTextField)
            {
                cf = new CustomField();
                cf.setValue(((JTextField)component).getText());
            }
            else if( component instanceof JTextArea)
            {
                cf = new CustomField();
                cf.setValue(((JTextArea)component).getText());
            }
            else if( component instanceof JComboBox)
            {
                cf = new CustomField();
                cf.setValue(((HtmlOptionLike)(((JComboBox)component).getSelectedItem())).getValue());
            }
            else if(component instanceof JDateChooser)
            {
                cf = new CustomField();
                cf.setValue(((JDateChooser)component).getDate().toString());
            }
            else if(component instanceof JCheckBox)
            {
                cf = new CustomField();
                cf.setValue(((JCheckBox)component).isSelected()?"1":"0");
            }

            if( cf != null )
            {
                cf.setName(component.getName());
                customFields.add(cf);
            }
        }
        return customFields.isEmpty() ? null : customFields;
    }
    
    private void uploadLogTimeEntry()
    {
        
    }

    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        customFieldsPanel = new javax.swing.JPanel();

        setMinimumSize(new java.awt.Dimension(550, 300));

        mainPanel.setMinimumSize(new java.awt.Dimension(0, 0));

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 700, Short.MAX_VALUE)
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        getContentPane().add(mainPanel, java.awt.BorderLayout.PAGE_START);

        javax.swing.GroupLayout customFieldsPanelLayout = new javax.swing.GroupLayout(customFieldsPanel);
        customFieldsPanel.setLayout(customFieldsPanelLayout);
        customFieldsPanelLayout.setHorizontalGroup(
            customFieldsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 700, Short.MAX_VALUE)
        );
        customFieldsPanelLayout.setVerticalGroup(
            customFieldsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        getContentPane().add(customFieldsPanel, java.awt.BorderLayout.PAGE_END);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-700)/2, (screenSize.height-450)/2, 700, 450);
    }// </editor-fold>//GEN-END:initComponents

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new LogTimeForm().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel customFieldsPanel;
    private javax.swing.JPanel mainPanel;
    // End of variables declaration//GEN-END:variables
}
